package com.greatchn.resource_server.config;

import com.greatchn.resource_server.constant.Constant;
import com.greatchn.resource_server.handler.AccessTokenConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;

import javax.annotation.Resource;
import javax.sql.DataSource;

/**
 * @ResourceServerConfig: 资源服务配置
 * @author: ZBoHang
 * @time: 2023/2/28 17:34
 */
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    public static final String RESIURCE_ID = "invoice_platfrom_resource_id";

    @Resource
    private AccessTokenConverter accessTokenConverter;
    @Resource
    private DataSource dataSource;

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.resourceId(RESIURCE_ID)
                .tokenServices(tokenServices())
                .stateless(Boolean.TRUE);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                // 资源服务器 除置换token意外 其它接口无需身份认证
                .antMatchers("/sale/getInfo").authenticated()
                .anyRequest()
                .permitAll()
                .and()
                // 跨域
                .cors().disable();
    }



    /**
     * 令牌服务配置
     */
    @Bean
    public ResourceServerTokenServices tokenServices() {

        DefaultTokenServices services = new DefaultTokenServices();
        // 配置令牌存储策略
        services.setTokenStore(tokenStore());
        // 增强转化
        services.setTokenEnhancer(jwtAccessTokenConverter());

        services.setClientDetailsService(jdbcClientDetailsService());

        return services;
    }

    /**
     * 令牌存储策略
     */
    @Bean
    public TokenStore tokenStore() {
        return new JwtTokenStore(jwtAccessTokenConverter());
    }

    /**
     * 令牌转化
     */
    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter() {
        JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
        jwtAccessTokenConverter.setSigningKey(Constant.JWT_SECRET_KEY);
        jwtAccessTokenConverter.setAccessTokenConverter(this.accessTokenConverter);
        return jwtAccessTokenConverter;
    }

    /**
     * 客户端信息
     */
    @Bean
    public JdbcClientDetailsService jdbcClientDetailsService() {
        return new JdbcClientDetailsService(this.dataSource);
    }
}
